构造编译器是一项复杂而迷人的任务。LLVM项目为编译器提供了可重用的组件，LLVM核心库实现了世界级的优化代码生成器，可以为所有主流CPU架构翻译与源语言无关的机器码中间表示，许多编程语言的编译器已经在使用LLVM。

本书将介绍如何实现自己的编译器，以及如何使用LLVM来实现。您将了解编译器的前端如何将源代码转换为抽象语法树，以及如何从中生成中间表示(IR)。此外，还将探索在编译器中添加一个优化管道，可将IR编译为高性能的机器码。

LLVM框架可以通过多种方式进行扩展，读者将了解如何向LLVM添加通道，甚至是一个全新的后端。高级主题，如编译不同的CPU架构和扩展clang和clang静态分析器与自己的插件和检查器也包括在内。本书遵循一种实用的方法，并附有示例源代码，读者可以在自己的项目中应用相应的代码。

\mySubsubsection{}{新版本增加的内容}

有一个新的章节，专门介绍在LLVM中使用的TableGen语言的概念和语法，读者可以利用它来定义类，记录和整个LLVM后端。此外，本书还介绍了后端开发的重点，其中讨论了可以为LLVM后端实现的各种新后端概念，例如：实现GlobalISel指令框架和开发机器功能通道。

\mySubsubsection{}{适读人群}

本书是为有兴趣学习LLVM框架的编译器开发人员、爱好者和工程师编写的。对于希望使用基于编译器的工具进行代码分析和改进的C++软件工程师，以及希望获得更多LLVM基本知识的LLVM库的工程师。要理解本书所涵盖的概念，必须具有C++中级编程经验。

\mySubsubsection{}{本书内容}

\textit{第1章，安装LLVM}，解释了如何设置和使用你的开发环境，了解如何自行编译LLVM库，以及自定义构建过程。

\textit{第2章，编译器的结构}，对编译器组件的概述，最后可以实现第一个生成LLVM IR的编译器。

\textit{第3章，将源码文件转换为抽象语法树}，详细介绍了如何实现编译器的前端。为一种小型编程语言创建前端编译器，最后构建抽象语法树。

\textit{第4章，生成IR代码的基础知识}，展示了如何从抽象语法树生成LLVM IR。将实现语言的编译器，生成汇编文本或目标代码文件。

\textit{第5章，高级语言结构生成的IR}，说明了如何将高级编程语言中常见的源语言特性转换为LLVM IR。将了解聚合数据类型的转换、实现类继承和虚函数的各种选项，以及如何遵循系统的应用程序二进制接口。

\textit{第6章，生成IR代码的进阶知识}，展示了如何在源语言中为异常处理语句生成LLVM IR。还将学习如何为基于类型的别名分析添加元数据，以及如何向生成的LLVM IR添加调试信息，并扩展编译器生成的元数据。

\textit{第7章，优化IR}，解释了LLVM通道管理器。将实现自己的通道，既作为LLVM的一部分，也作为插件，将了解如何将通道添加到优化通道流水线中。

\textit{第8章，TableGen语言}，介绍了LLVM自己的领域特定语言TableGen。该语言用于减少开发人员的编码工作，将了解在TableGen语言中定义数据的不同方法，以及如何在后端使用。

\textit{第9章，JIT编译}，讨论了如何使用LLVM实现一个即时(JIT)编译器。将以两种不同的方式为LLVM IR实现自己的JIT编译器。

\textit{第10章，使用LLVM工具进行调试}，探讨了LLVM的各种库和组件的细节，可以识别应用程序中的错误，使用消毒器来识别缓冲区溢出和其他错误；使用libFuzzer库，使用随机数据作为输入来测试函数；XRay将帮助程序找到性能瓶颈。可使用clang静态分析器在源代码级别识别错误，并且将了解到可以向分析器添加自己的检查器，还将了解如何使用自己的插件对clang进行扩展。

\textit{第11章，目标描述}，解释了如何添加对新的CPU架构的支持。本章讨论了必要的和可选的步骤，如定义寄存器和指令，开发指令选择，以及支持汇编和反汇编程序。

\textit{第12章，指令选择}，演示了两种不同的指令选择方法，特别解释了SelectionDAG和GlobalISel是如何工作的，并展示了如何在目标中实现这些功能，基于前一章的例子。此外，将了解如何对指令选择进行调试和测试。

\textit{第13章，超越指令选择}，解释了如何通过探索超越指令选择的概念来完成后端实现。这包括添加新的机器通道来实现特定于目标的任务，这些主题对于简单后端来说是不必要的，但对于高度优化的后端来说是有趣的，例如：交叉编译到另一个CPU架构。

\mySubsubsection{}{编译环境}

您需要一台运行Linux、Windows、Mac OS X或FreeBSD的计算机，并为操作系统安装了开发工具链。所需工具请参见表格，所有工具都需要配置到shell的搜索路径中。

% Please add the following required packages to your document preamble:
% \usepackage{longtable}
% Note: It may be necessary to compile the document several times to get a multi-page table to line up properly
\begin{longtable}{|l|l|}
\hline
\textbf{书中涉及的软件/硬件} & \textbf{操作系统} \\ \hline
\endfirsthead
%
\endhead
%
\begin{tabular}[c]{@{}l@{}}C/C++编译器:\\ gcc 7.1.0或更高版本, clang 3.0或更高版本,\\ Apple clang 10.0 或更高版本,\\ Visual Studio 2019 16.7或更高版本\end{tabular} &
\begin{tabular}[c]{@{}l@{}}Linux(any), Windows,\\ Mac OS X或FreeBSD\end{tabular} \\ \hline
CMake 3.20.0或更高版本                          & \\ \hline
Ninja 1.11.1                                   & \\ \hline
Python 3.6或更高版本                            & \\ \hline
Git 2.39或更高版本                   & \\ \hline
\end{longtable}


要创建第10章“使用LLVM工具调试”中的火焰图，需要从\url{https://github.com/brendangregg/FlameGraph}获取安装脚本。要运行安装脚本，还需要安装最新版本的Perl。要查看图形，还需要能够显示SVG文件的Web浏览器，这是所有现代浏览器都能做到的。要在同一章中查看Chrome Trace Viewer可视化，需要安装Chrome浏览器。

\textbf{如果正在使用本书的数字版本，我们建议您自己输入代码或通过GitHub存储库访问代码(下一节提供链接)，将避免复制和粘贴代码。}

\mySubsubsection{}{下载示例}

可以从GitHub网站\url{https://github.com/PacktPublishing/Learn-LLVM-17}下载本书的示例代码。如果有对代码的更新，也会在现有的GitHub存储库中更新。

我们还在\url{https://github.com/PacktPublishing/}上提供了丰富的图书和视频目录中的其他代码包。可以一起拿来看看!


\mySubsubsection{}{联系方式}

我们欢迎读者的反馈。

\textbf{反馈}：如果你对这本书的任何方面有疑问，需要在你的信息的主题中提到书名，并给我们发邮件到\url{customercare@packtpub.com}。

\textbf{勘误}：尽管我们谨慎地确保内容的准确性，但错误还是会发生。如果您在本书中发现了错误，请向我们报告，我们将不胜感激。请访问\url{www.packtpub.com/support/errata}，选择相应书籍，点击勘误表提交表单链接，并输入详细信息。

\textbf{盗版}:如果您在互联网上发现任何形式的非法拷贝，非常感谢您提供地址或网站名称。请通过\url{copyright@packt.com}与我们联系，并提供材料链接。

\textbf{如果对成为书籍作者感兴趣}：如果你对某主题有专长，又想写一本书或为之撰稿，请访问\url{authors.packtpub.com}。


\mySubsubsection{}{欢迎评论}

我们很想听听读者们对本书的看法!欢迎请点击这里直接进入这本书的亚马逊评论页面，分享你的反馈。

您的评论对我们和技术社区都很重要，将帮助确保书籍内容的品质。

